from PyQt4 import QtCore, QtGui
import threading

#convert string to hex
def toHex(s):
    lst = []
    for ch in s:
        hv = hex(ord(ch)).replace('0x', '')
        if len(hv) == 1:
            hv = '0'+hv
        lst.append(hv)
    
    return reduce(lambda x,y:x+y, lst)


MD5_LENGTH = 32

def GetUnSpcaceString(qstring, start_index):
    for i in range(start_index, qstring.size()):
        if qstring.at(i).isSpace():
            break;
    return qstring.mid(start_index, i - start_index + 1)


def IsHexable(string):
    bMatched = True
    for i in range(0, MD5_LENGTH-1):
        char = string.at(i).toAscii()
        if char.isdigit() or (char >= 'a' and char <= 'f') or (char >= 'A' and char <= 'F'):
            continue
        bMatched = False
        break
    return bMatched



class MD5Extracter(threading.Thread):
    class Delegate:
        def OnMD5Found(self, md5):
            pass

    def __init__(self, observer):
        threading.Thread.__init__(self)
        self.observer = observer
        self.qstring = ""
        self.work_event = threading.Event()
        self.start()

    def Extract(self, qstring):
        self.qstring = qstring
        self.work_event.set()

    def run(self):
        while True:
            self.work_event.clear()
            self.work_event.wait()
            self.__Extract()


    def __Extract(self):
        i = 0
        while (i < self.qstring.size()):
            str = GetUnSpcaceString(self.qstring, i)
            i += str.size()
            str = str.trimmed()
            if not (str.size() == MD5_LENGTH):
                continue
            if IsHexable(str):
                self.observer.OnMD5Found(str)
                
                
class Tester():
    def OnMD5Found(self, md5):
        print md5
    def Test(self):
        qstr = QtCore.QString("abcd654645645654645645645654654 \r\n 1234567890ABCDEF1234567890ABCDEF \rij klmno pqrs t uvw")
        md5_extracter = MD5Extracter(self)
        md5_extracter.Extract(qstr)
        
if __name__ == '__main__':
    t = Tester()
    t.Test()
    